package com.loper7.base.utils.img;

import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader.TileMode;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.provider.MediaStore;
import android.util.Log;
import android.widget.TextView;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URI;

public class ImageUtils {

/* Options used internally. */

    private static final int OPTIONS_NONE = 0x0;

    private static final int OPTIONS_SCALE_UP = 0x1;

    public static final int OPTIONS_RECYCLE_INPUT = 0x2;

    /**
     * 获得圆角图片
     *
     * @param bitmap
     * @param roundPx
     * @return
     */

    public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, float roundPx) {

        Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Config.ARGB_8888);

        Canvas canvas = new Canvas(output);

        final int color = 0xff424242;

        final Paint paint = new Paint();

        final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());

        final RectF rectF = new RectF(rect);

        paint.setAntiAlias(true);

        canvas.drawARGB(0, 0, 0, 0);

        paint.setColor(color);

        canvas.drawRoundRect(rectF, roundPx, roundPx, paint);

        paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));

        canvas.drawBitmap(bitmap, rect, rect, paint);

        return output;

    }

    /**
     * 获得带倒影的图片方法
     *
     * @param bitmap
     * @return
     */

    public static Bitmap getReflectionImageWithOrigin(Bitmap bitmap) {

        final int reflectionGap = 4;

        int width = bitmap.getWidth();

        int height = bitmap.getHeight();

        Matrix matrix = new Matrix();

        matrix.preScale(1, -1);

        Bitmap reflectionImage = Bitmap.createBitmap(bitmap,

                0, height / 2, width, height / 2, matrix, false);

        Bitmap bitmapWithReflection = Bitmap.createBitmap(width, (height + height / 2), Config.ARGB_8888);

        Canvas canvas = new Canvas(bitmapWithReflection);

        canvas.drawBitmap(bitmap, 0, 0, null);

        Paint deafalutPaint = new Paint();

        canvas.drawRect(0, height, width, height + reflectionGap,

                deafalutPaint);

        canvas.drawBitmap(reflectionImage, 0, height + reflectionGap, null);

        Paint paint = new Paint();

        LinearGradient shader = new LinearGradient(0,

                bitmap.getHeight(), 0, bitmapWithReflection.getHeight()

                + reflectionGap, 0x70ffffff, 0x00ffffff, TileMode.CLAMP);

        paint.setShader(shader);

// Set the Transfer mode to be porter duff and destination in

        paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));

// Draw a rectangle using the paint with our linear gradient

        canvas.drawRect(0, height, width, bitmapWithReflection.getHeight()

                + reflectionGap, paint);

        return bitmapWithReflection;

    }

    /**
     * 将Drawable转化为Bitmap
     *
     * @param drawable
     * @return
     */

    public static Bitmap drawableToBitmap(Drawable drawable) {

        int width = drawable.getIntrinsicWidth();

        int height = drawable.getIntrinsicHeight();

        Bitmap bitmap = Bitmap.createBitmap(width, height,

                drawable.getOpacity() != PixelFormat.OPAQUE ? Config.ARGB_8888

                        : Config.RGB_565);

        Canvas canvas = new Canvas(bitmap);

        drawable.setBounds(0, 0, width, height);

        drawable.draw(canvas);

        return bitmap;

    }

    /**
     * 按图片大小(字节大小)压缩图片
     *
     * @param path
     * @return
     */

    public static Bitmap fitSizeImg(String path) {

        if (path == null || path.length() < 1) return null;

        File file = new File(path);

        Bitmap resizeBmp = null;

        BitmapFactory.Options opts = new BitmapFactory.Options();

// 数字越大读出的图片占用的heap越小 不然总是溢出

        if (file.length() < 20480) {      // 0-20k

            opts.inSampleSize = 1;

        } else if (file.length() < 51200) { // 20-50k

            opts.inSampleSize = 2;

        } else if (file.length() < 307200) { // 50-300k

            opts.inSampleSize = 4;

        } else if (file.length() < 819200) { // 300-800k

            opts.inSampleSize = 6;

        } else if (file.length() < 1048576) { // 800-1024k

            opts.inSampleSize = 8;

        } else if (file.length() < 2097152) { // 1024k-2MB

            opts.inSampleSize = 16;

        } else if (file.length() < 3145728) { // 2MB-3MB

            opts.inSampleSize = 24;

        } else if (file.length() < 4094304) { // 3MB-4MB

            opts.inSampleSize = 32;

        } else {
            opts.inSampleSize = 50;
        }
        Log.d("asd", file.length() + "压缩比" + opts.inSampleSize);
        resizeBmp = BitmapFactory.decodeFile(file.getPath(), opts);
        Log.d("asd", "压缩后" + resizeBmp.getByteCount());

        return resizeBmp;

    }

    /**
     * 按图片大小(字节大小)压缩图片
     *
     * @param uri
     * @return
     */

    public static Bitmap fitSizeImg(URI uri) {

        if (uri == null) return null;

        File file = new File(uri);

        Bitmap resizeBmp = null;

        BitmapFactory.Options opts = new BitmapFactory.Options();

// 数字越大读出的图片占用的heap越小 不然总是溢出

        if (file.length() < 20480) {      // 0-20k

            opts.inSampleSize = 1;

        } else if (file.length() < 51200) { // 20-50k

            opts.inSampleSize = 2;

        }/* else if (file.length() < 307200) { // 50-300k

            opts.inSampleSize = 4;

        } else if (file.length() < 819200) { // 300-800k

            opts.inSampleSize = 6;

        } else if (file.length() < 1048576) { // 800-1024k

            opts.inSampleSize = 8;

        }else if (file.length() < 2097152) { // 1024k-2MB

            opts.inSampleSize = 16;

        }else if (file.length() < 3145728) { // 2MB-3MB

            opts.inSampleSize = 24;

        }else if (file.length() < 4094304) { // 800-1024k

            opts.inSampleSize = 32;

        } */ else {

            //opts.inSampleSize = 10;
            opts.inSampleSize = (int) (file.length() / 51200);


        }


        resizeBmp = BitmapFactory.decodeFile(file.getPath(), opts);

        return resizeBmp;

    }

    /**
     * 缩放图片
     *
     * @param source 源文件(Bitmap类型)
     * @param width  输出缩略图的宽度
     * @param height 输出缩略图的高度
     * @return
     */

    public static Bitmap extractThumbnail(

            Bitmap source, int width, int height) {

        return extractThumbnail(source, width, height, OPTIONS_NONE);

    }

    /**
     * 缩放图片
     *
     * @param source  源文件(Bitmap类型)
     * @param width   输出缩略图的宽度
     * @param height  输出缩略图的高度
     * @param options 如果options定义为OPTIONS_RECYCLE_INPUT,则回收@param source这个资源文件
     *                <p/>
     *                (除非缩略图等于@param source)
     * @return
     */

    public static Bitmap extractThumbnail(Bitmap source, int width, int height, int options) {

        if (source == null) {

            return null;

        }

        float scale;

        if (source.getWidth() < source.getHeight()) {

            scale = width / (float) source.getWidth();

        } else {

            scale = height / (float) source.getHeight();

        }

        Matrix matrix = new Matrix();

        matrix.setScale(scale, scale);

        Bitmap thumbnail = transform(matrix, source, width, height, OPTIONS_SCALE_UP | options);

        return thumbnail;

    }

    /**
     * Transform source Bitmap to targeted width and height.
     */

    private static Bitmap transform(Matrix scaler, Bitmap source, int targetWidth, int targetHeight, int options) {
        boolean scaleUp = (options & OPTIONS_SCALE_UP) != 0;
        boolean recycle = (options & OPTIONS_RECYCLE_INPUT) != 0;
        int deltaX = source.getWidth() - targetWidth;
        int deltaY = source.getHeight() - targetHeight;
        if (!scaleUp && (deltaX < 0 || deltaY < 0)) {
/*

* In this case the bitmap is smaller, at least in one dimension,

* than the target.  Transform it by placing as much of the image

* as possible into the target and leaving the top/bottom or

* left/right (or both) black.

*/
            Bitmap b2 = Bitmap.createBitmap(targetWidth, targetHeight,
                    Config.ARGB_8888);
            Canvas c = new Canvas(b2);
            int deltaXHalf = Math.max(0, deltaX / 2);
            int deltaYHalf = Math.max(0, deltaY / 2);
            Rect src = new Rect(
                    deltaXHalf,
                    deltaYHalf,
                    deltaXHalf + Math.min(targetWidth, source.getWidth()),
                    deltaYHalf + Math.min(targetHeight, source.getHeight()));
            int dstX = (targetWidth - src.width()) / 2;
            int dstY = (targetHeight - src.height()) / 2;
            Rect dst = new Rect(
                    dstX,
                    dstY,
                    targetWidth - dstX,
                    targetHeight - dstY);
            c.drawBitmap(source, src, dst, null);
            if (recycle) {
                source.recycle();
            }
            return b2;
        }
        float bitmapWidthF = source.getWidth();
        float bitmapHeightF = source.getHeight();
        float bitmapAspect = bitmapWidthF / bitmapHeightF;
        float viewAspect = (float) targetWidth / targetHeight;
        if (bitmapAspect > viewAspect) {
            float scale = targetHeight / bitmapHeightF;
            if (scale < .9F || scale > 1F) {
                scaler.setScale(scale, scale);
            } else {
                scaler = null;
            }
        } else {
            float scale = targetWidth / bitmapWidthF;
            if (scale < .9F || scale > 1F) {
                scaler.setScale(scale, scale);
            } else {
                scaler = null;
            }
        }
        Bitmap b1;
        if (scaler != null) {
// this is used for minithumb and crop, so we want to filter here.
            b1 = Bitmap.createBitmap(source, 0, 0,
                    source.getWidth(), source.getHeight(), scaler, true);
        } else {
            b1 = source;
        }
        if (recycle && b1 != source) {
            source.recycle();
        }
        int dx1 = Math.max(0, b1.getWidth() - targetWidth);
        int dy1 = Math.max(0, b1.getHeight() - targetHeight);
        Bitmap b2 = Bitmap.createBitmap(
                b1,
                dx1 / 2,
                dy1 / 2,
                targetWidth,
                targetHeight);
        if (b2 != b1) {
            if (recycle || b1 != source) {
                b1.recycle();
            }
        }
        return b2;
    }

    /**
     * 4.2版 新增    zuoshengyong
     * <p/>
     * 按图片大小(先压缩尺寸 在压缩质量)压缩图片
     *
     * @param srcPath
     * @return
     */

    public static Bitmap getImage(String srcPath) {

        BitmapFactory.Options newOpts = new BitmapFactory.Options();

// 开始读入图片，此时把options.inJustDecodeBounds 设回true了

        newOpts.inJustDecodeBounds = true;

        Bitmap bitmap = BitmapFactory.decodeFile(srcPath, newOpts);// 此时返回bm为空

        newOpts.inJustDecodeBounds = false;

        int w = newOpts.outWidth;

        int h = newOpts.outHeight;

        float hh = 600f;// 这里设置高度为800f

        float ww = 600f;// 这里设置宽度为480f

// 缩放比。由于是固定比例缩放，只用高或者宽其中一个数据进行计算即可

        int be = 1;// be=1表示不缩放

        if (w > h && w > ww) {

            be = (int) (newOpts.outWidth / ww);

        } else if (w < h && h > hh) {

            be = (int) (newOpts.outHeight / hh);

        }

        if (be <= 0)

            be = 1;

        newOpts.inSampleSize = be;// 设置缩放比例

        bitmap = BitmapFactory.decodeFile(srcPath, newOpts);

      /*  UtilsLog.e("TAG", "after scaled bitmap width:" + bitmap.getWidth());

        UtilsLog.e("TAG", "after scaled bitmap height:" + bitmap.getHeight());

        UtilsLog.e("TAG", "after scaled newOpts width:" + newOpts.outWidth);

        UtilsLog.e("TAG", "after scaled newOpts height:" + newOpts.outHeight);*/

        return bitmap;// 压缩好比例大小后再进行质量压缩

    }

    /**
     * 保存方法
     */
    public static String saveCroppedImage(Bitmap bmp, String name) {
        File file = new File("/sdcard/myFolder");
        if (!file.exists())
            file.mkdir();

        file = new File(name.trim());
        String fileName = file.getName();
        String mName = fileName.substring(0, fileName.lastIndexOf("."));
        String sName = fileName.substring(fileName.lastIndexOf("."));

        // /sdcard/myFolder/temp_cropped.jpg
        String newFilePath = "/sdcard/myFolder" + "/" + mName + "_cropped" + sName;
        file = new File(newFilePath);
        try {
            file.createNewFile();
            FileOutputStream fos = new FileOutputStream(file);
            bmp.compress(Bitmap.CompressFormat.JPEG, 50, fos);
            fos.flush();
            fos.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return newFilePath;
    }

    /*
    * 通过uri获取绝对路径
    * */
    public static String getAbsoluteImagePath(Context context, Uri uri) {
        // can post image
        String[] proj = {MediaStore.Images.Media.DATA};
        Cursor cursor = context.getContentResolver().query(uri,
                proj,                 // Which columns to return
                null,       // WHERE clause; which rows to return (all rows)
                null,       // WHERE clause selection arguments (none)
                null);                 // Order-by clause (ascending by name)

        int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();

        return cursor.getString(column_index);
    }

    public static void setDrawableRight(Context context, int resId, TextView tv) {
        if (resId == 0) {
            tv.setCompoundDrawables(null, null, null, null);
            return;
        }
        Drawable drawableRight = context.getResources().getDrawable(resId);
        drawableRight.setBounds(0, 0, drawableRight.getMinimumWidth(), drawableRight.getMinimumHeight());
        tv.setCompoundDrawables(null, null, drawableRight, null);
    }

    public static void setDrawableTop(Context context, int resId, TextView tv) {
        if (resId == 0) {
            tv.setCompoundDrawables(null, null, null, null);
            return;
        }
        Drawable drawableTop = context.getResources().getDrawable(resId);
        drawableTop.setBounds(0, 0, drawableTop.getMinimumWidth(), drawableTop.getMinimumHeight());
        tv.setCompoundDrawables(null, drawableTop, null, null);
    }

}